home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / CONTAS2.PAK / CONTRVW.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  11KB  |  430 lines

  1. // ContrVw.cpp : implementation of the CContainerView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Contain.h"
  6.  
  7. #include "ContrDoc.h"
  8. #include "CntrItem.h"
  9. #include "ContrVw.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CContainerView
  19.  
  20. IMPLEMENT_DYNCREATE(CContainerView, CView)
  21.  
  22. BEGIN_MESSAGE_MAP(CContainerView, CView)
  23.     //{{AFX_MSG_MAP(CContainerView)
  24.         // NOTE - the ClassWizard will add and remove mapping macros here.
  25.         //    DO NOT EDIT what you see in these blocks of generated code!
  26.     ON_WM_SETFOCUS()
  27.     ON_WM_SIZE()
  28.     ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
  29.     ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
  30.     ON_WM_LBUTTONDOWN()
  31.     ON_WM_LBUTTONDBLCLK()
  32.     ON_WM_SETCURSOR()
  33.     ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
  34.     ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
  35.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  36.     ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  37.     ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  38.     //}}AFX_MSG_MAP
  39.     // Standard printing commands
  40.     ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  41.     ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  42.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  43. END_MESSAGE_MAP()
  44.  
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CContainerView construction/destruction
  47.  
  48. CContainerView::CContainerView()
  49. {
  50.     m_pSelection = NULL;
  51.     // TODO: add construction code here
  52.  
  53. }
  54.  
  55. CContainerView::~CContainerView()
  56. {
  57. }
  58.  
  59. BOOL CContainerView::PreCreateWindow(CREATESTRUCT& cs)
  60. {
  61.     // TODO: Modify the Window class or styles here by modifying
  62.     //  the CREATESTRUCT cs
  63.  
  64.     return CView::PreCreateWindow(cs);
  65. }
  66.  
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CContainerView drawing
  69.  
  70. void CContainerView::OnDraw(CDC* pDC)
  71. {
  72.     CContainerDoc* pDoc = GetDocument();
  73.     ASSERT_VALID(pDoc);
  74.  
  75.     // draw the OLE items from the list
  76.     POSITION pos = pDoc->GetStartPosition();
  77.     while (pos != NULL)
  78.     {
  79.         // draw the item
  80.         CContainerItem* pItem = (CContainerItem*)pDoc->GetNextItem(pos);
  81.         pItem->Draw(pDC, pItem->m_rect);
  82.  
  83.         // draw the tracker over the item
  84.         CRectTracker tracker;
  85.         SetupTracker(pItem, &tracker);
  86.         tracker.Draw(pDC);
  87.     }
  88. }
  89.  
  90. void CContainerView::OnInitialUpdate()
  91. {
  92.     CView::OnInitialUpdate();
  93.  
  94.     // TODO: remove this code when final selection model code is written
  95.     m_pSelection = NULL;    // initialize selection
  96.  
  97. }
  98.  
  99. /////////////////////////////////////////////////////////////////////////////
  100. // CContainerView printing
  101.  
  102. BOOL CContainerView::OnPreparePrinting(CPrintInfo* pInfo)
  103. {
  104.     // default preparation
  105.     return DoPreparePrinting(pInfo);
  106. }
  107.  
  108. void CContainerView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  109. {
  110.     // TODO: add extra initialization before printing
  111. }
  112.  
  113. void CContainerView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  114. {
  115.     // TODO: add cleanup after printing
  116. }
  117.  
  118. /////////////////////////////////////////////////////////////////////////////
  119. // OLE Client support and commands
  120.  
  121. BOOL CContainerView::IsSelected(const CObject* pDocItem) const
  122. {
  123.     // The implementation below is adequate if your selection consists of
  124.     //  only CContainerItem objects.  To handle different selection
  125.     //  mechanisms, the implementation here should be replaced.
  126.  
  127.     // TODO: implement this function that tests for a selected OLE client item
  128.  
  129.     return pDocItem == m_pSelection;
  130. }
  131.  
  132. void CContainerView::OnInsertObject()
  133. {
  134.     // Invoke the standard Insert Object dialog box to obtain information
  135.     //  for new CContainerItem object.
  136.     COleInsertDialog dlg;
  137.     if (dlg.DoModal() != IDOK)
  138.         return;
  139.  
  140.     BeginWaitCursor();
  141.  
  142.     CContainerItem* pItem = NULL;
  143.     TRY
  144.     {
  145.         // Create new item connected to this document.
  146.         CContainerDoc* pDoc = GetDocument();
  147.         ASSERT_VALID(pDoc);
  148.         pItem = new CContainerItem(pDoc);
  149.         ASSERT_VALID(pItem);
  150.  
  151.         // Initialize the item from the dialog data.
  152.         if (!dlg.CreateItem(pItem))
  153.             AfxThrowMemoryException();  // any exception will do
  154.         ASSERT_VALID(pItem);
  155.         pItem->UpdateLink();
  156.         pItem->UpdateFromServerExtent();
  157.  
  158.         // If item created from class list (not from file) then launch
  159.         //  the server to edit the item.
  160.         if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
  161.             pItem->DoVerb(OLEIVERB_SHOW, this);
  162.  
  163.         ASSERT_VALID(pItem);
  164.  
  165.         SetSelection(pItem);
  166.         pItem->InvalidateItem();
  167.     }
  168.     CATCH(CException, e)
  169.     {
  170.         if (pItem != NULL)
  171.         {
  172.             ASSERT_VALID(pItem);
  173.             pItem->Delete();
  174.         }
  175.         AfxMessageBox(IDP_FAILED_TO_CREATE);
  176.     }
  177.     END_CATCH
  178.  
  179.     EndWaitCursor();
  180. }
  181.  
  182. // The following command handler provides the standard keyboard
  183. //  user interface to cancel an in-place editing session.  Here,
  184. //  the container (not the server) causes the deactivation.
  185. void CContainerView::OnCancelEditCntr()
  186. {
  187.     // Close any in-place active item on this view.
  188.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  189.     if (pActiveItem != NULL)
  190.     {
  191.         pActiveItem->Close();
  192.     }
  193.     ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
  194. }
  195.  
  196. // Special handling of OnSetFocus and OnSize are required for a container
  197. //  when an object is being edited in-place.
  198. void CContainerView::OnSetFocus(CWnd* pOldWnd)
  199. {
  200.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  201.     if (pActiveItem != NULL &&
  202.         pActiveItem->GetItemState() == COleClientItem::activeUIState)
  203.     {
  204.         // need to set focus to this item if it is in the same view
  205.         CWnd* pWnd = pActiveItem->GetInPlaceWindow();
  206.         if (pWnd != NULL)
  207.         {
  208.             pWnd->SetFocus();   // don't call the base class
  209.             return;
  210.         }
  211.     }
  212.  
  213.     CView::OnSetFocus(pOldWnd);
  214. }
  215.  
  216. void CContainerView::OnSize(UINT nType, int cx, int cy)
  217. {
  218.     CView::OnSize(nType, cx, cy);
  219.     COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  220.     if (pActiveItem != NULL)
  221.         pActiveItem->SetItemRects();
  222. }
  223. CContainerItem* CContainerView::HitTestItems(CPoint point)
  224. {
  225.     CContainerDoc* pDoc = GetDocument();
  226.     CContainerItem* pItemHit = NULL;
  227.     POSITION pos = pDoc->GetStartPosition();
  228.     while (pos != NULL)
  229.     {
  230.         CContainerItem* pItem = (CContainerItem*)pDoc->GetNextItem(pos);
  231.         if (pItem->m_rect.PtInRect(point))
  232.             pItemHit = pItem;
  233.     }
  234.     return pItemHit;    // return top item at point
  235. }
  236.  
  237. void CContainerView::SetSelection(CContainerItem* pItem)
  238. {
  239.     // close in-place active item
  240.     if (pItem == NULL || m_pSelection != pItem)
  241.     {
  242.         COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
  243.         if (pActiveItem != NULL && pActiveItem != pItem)
  244.             pActiveItem->Close();
  245.     }
  246.     // update view to new selection
  247.     if (m_pSelection != pItem)
  248.     {
  249.         if (m_pSelection != NULL)
  250.             OnUpdate(NULL, HINT_UPDATE_ITEM, m_pSelection);
  251.  
  252.         m_pSelection = pItem;
  253.         if (m_pSelection != NULL)
  254.             OnUpdate(NULL, HINT_UPDATE_ITEM, m_pSelection);
  255.     }
  256. }
  257.  
  258. void CContainerView::SetupTracker(CContainerItem* pItem, CRectTracker* pTracker)
  259. {
  260.     pTracker->m_rect = pItem->m_rect;
  261.  
  262.     if (pItem == m_pSelection)
  263.         pTracker->m_nStyle |= CRectTracker::resizeInside;
  264.  
  265.     if (pItem->GetType() == OT_LINK)
  266.         pTracker->m_nStyle |= CRectTracker::dottedLine;
  267.     else
  268.         pTracker->m_nStyle |= CRectTracker::solidLine;
  269.  
  270.     if (pItem->GetItemState() == COleClientItem::openState ||
  271.         pItem->GetItemState() == COleClientItem::activeUIState)
  272.     {
  273.         pTracker->m_nStyle |= CRectTracker::hatchInside;
  274.     }
  275. }
  276.  
  277.  
  278. /////////////////////////////////////////////////////////////////////////////
  279. // CContainerView diagnostics
  280.  
  281. #ifdef _DEBUG
  282. void CContainerView::AssertValid() const
  283. {
  284.     CView::AssertValid();
  285. }
  286.  
  287. void CContainerView::Dump(CDumpContext& dc) const
  288. {
  289.     CView::Dump(dc);
  290. }
  291.  
  292. CContainerDoc* CContainerView::GetDocument() // non-debug version is inline
  293. {
  294.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CContainerDoc)));
  295.     return (CContainerDoc*)m_pDocument;
  296. }
  297. #endif //_DEBUG
  298.  
  299. /////////////////////////////////////////////////////////////////////////////
  300. // CContainerView message handlers
  301. void CContainerView::OnLButtonDown(UINT nFlags, CPoint point)
  302. {
  303.     CContainerItem* pItemHit = HitTestItems(point);
  304.     SetSelection(pItemHit);
  305.  
  306.     if (pItemHit != NULL)
  307.     {
  308.         CRectTracker tracker;
  309.         SetupTracker(pItemHit, &tracker);
  310.  
  311.         UpdateWindow();
  312.         if (tracker.Track(this, point))
  313.         {
  314.             pItemHit->InvalidateItem();
  315.             pItemHit->m_rect = tracker.m_rect;
  316.             pItemHit->InvalidateItem();
  317.             GetDocument()->SetModifiedFlag();
  318.         }
  319.     }
  320.  
  321.     CView::OnLButtonDown(nFlags, point);
  322. }
  323.  
  324. void CContainerView::OnLButtonDblClk(UINT nFlags, CPoint point)
  325. {
  326.     OnLButtonDown(nFlags, point);
  327.  
  328.     if (m_pSelection != NULL)
  329.     {
  330.         m_pSelection->DoVerb(GetKeyState(VK_CONTROL) < 0 ?
  331.             OLEIVERB_OPEN : OLEIVERB_PRIMARY, this);
  332.     }
  333.  
  334.     CView::OnLButtonDblClk(nFlags, point);
  335. }
  336.  
  337. BOOL CContainerView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  338. {
  339.     if (pWnd == this && m_pSelection != NULL)
  340.     {
  341.         // give the tracker for the selection a chance
  342.         CRectTracker tracker;
  343.         SetupTracker(m_pSelection, &tracker);
  344.         if (tracker.SetCursor(this, nHitTest))
  345.             return TRUE;
  346.     }
  347.  
  348.     return CView::OnSetCursor(pWnd, nHitTest, message);
  349. }
  350.  
  351. void CContainerView::OnEditClear()
  352. {
  353.     if (m_pSelection != NULL)
  354.     {
  355.         m_pSelection->Delete();
  356.         m_pSelection = NULL;
  357.         GetDocument()->UpdateAllViews(NULL);
  358.     }
  359. }
  360.  
  361. void CContainerView::OnUpdateEditClear(CCmdUI* pCmdUI)
  362. {
  363.     pCmdUI->Enable(m_pSelection != NULL);
  364.  
  365. }
  366. void CContainerView::OnEditCopy()
  367. {
  368.     if (m_pSelection != NULL)
  369.         m_pSelection->CopyToClipboard();
  370. }
  371.  
  372. void CContainerView::OnUpdateEditCopy(CCmdUI* pCmdUI)
  373. {
  374.     pCmdUI->Enable(m_pSelection != NULL);
  375. }
  376.  
  377. void CContainerView::OnEditPaste()
  378. {
  379.     CContainerItem* pItem = NULL;
  380.  
  381.     TRY
  382.     {
  383.         // Create new item connected to this document.
  384.         CContainerDoc* pDoc = GetDocument();
  385.         ASSERT_VALID(pDoc);
  386.         pItem = new CContainerItem(pDoc);
  387.         ASSERT_VALID(pItem);
  388.  
  389.         // Initialize the item from clipboard data
  390.         if (!pItem->CreateFromClipboard())
  391.             AfxThrowMemoryException();  // any exception will do
  392.         ASSERT_VALID(pItem);
  393.  
  394.         // update the size before displaying
  395.         pItem->UpdateFromServerExtent();
  396.  
  397.         // set selection to newly pasted item
  398.         SetSelection(pItem);
  399.         pItem->InvalidateItem();
  400.     }
  401.     CATCH(CException, e)
  402.     {
  403.         if (pItem != NULL)
  404.         {
  405.             ASSERT_VALID(pItem);
  406.             pItem->Delete();
  407.         }
  408.         AfxMessageBox(IDP_FAILED_TO_CREATE);
  409.     }
  410.     END_CATCH
  411. }
  412. void CContainerView::OnUpdate(CView* /* pSender */, LPARAM lHint, CObject* pHint)
  413. {
  414.     switch (lHint)
  415.     {
  416.     case HINT_UPDATE_WINDOW:    // invalidate entire window
  417.         Invalidate();
  418.         break;
  419.     case HINT_UPDATE_ITEM:      // invalidate single item
  420.         {
  421.             CRectTracker tracker;
  422.             SetupTracker((CContainerItem*)pHint, &tracker);
  423.             CRect rect;
  424.             tracker.GetTrueRect(rect);
  425.             InvalidateRect(rect);
  426.         }
  427.         break;
  428.     }
  429. }
  430.